package com.ddsso.auth.web.repository.impl;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ddsso.auth.web.repository.LoginDao;
import com.ddsso.auth.web.repository.impl.BaseDaoImpl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author zdd
 * @package com.ddsso.auth.dao.impl
 * @Time Created by zdd on 2016/11/3.
 * @description To-do
 */
@Component("loginDao")
public class LoginDaoImpl extends BaseDaoImpl<HashSet<String>> implements LoginDao {
    protected Logger logger = LoggerFactory.getLogger(getClass());


    /**
     * 相同账号的T出
     * @description 1.对于多浏览器的东西，如果在session.customerid.userid中已经存了sessionid的情况下，
     * 2.需要将以前的先获取，然后删除对应存储的session然后在清除当前的session.customerid.userid
     * @param customerId
     * @param currentSessionId
     */
    public void syncSession(String customerId, String currentSessionId) {
        //1.根据用户id作为key从redis获取session_id
        Set<String> oldSessionIdSet=this.fetch(getBackwardSessionKey(customerId), HashSet.class);
        HashSet<String> newSessionIdSet=oldSessionIdSet!=null?new HashSet<String>(oldSessionIdSet):new HashSet<String>();
        logger.info("get backward sessions");
        // 2. 遍历 sessionId, 不存在于正向会话, 则移除
        for (Iterator<String> iterator = newSessionIdSet.iterator(); iterator.hasNext();) {
            String sessionId = iterator.next();
            if (!StringUtils.equals(sessionId, currentSessionId) ) {
                logger.info("remove invalid backward session:" + sessionId);
                if(this.get(getForwardSessionKey(sessionId))!=null){
                    this.remove(getForwardSessionKey(sessionId));
                }
                iterator.remove();
            }
        }
        // 3. 更新反向会话
        newSessionIdSet.add(currentSessionId);
        if (oldSessionIdSet==null||!oldSessionIdSet.equals(newSessionIdSet)) {
            logger.info("update backward session:"+currentSessionId);
            this.save(getBackwardSessionKey(customerId),newSessionIdSet);
        }
    }

    /**
     * @description 退出更新sessionid中的值
     * @param customerId
     * @param excludedSessionId
     * @param backwardSessionKey
     * @param forwardSessionKey
     */
    public void invalidSession(String customerId, String excludedSessionId,String backwardSessionKey,String forwardSessionKey) {
        // 1. 取出 sessionIdSet
        Set<String> sessionIdSet=this.fetch(getBackwardSessionKey(customerId), HashSet.class);
        if (sessionIdSet == null) {
            logger.info("backward session is empty");
            return;
        }

        for (Iterator<String> iterator = sessionIdSet.iterator(); iterator.hasNext();) {
            String sessionId = iterator.next();
            if (StringUtils.equals(String.valueOf(sessionId), excludedSessionId)) {
                continue;
            }
            if(this.get(getForwardSessionKey(sessionId))!=null){
                this.remove(getForwardSessionKey(sessionId));
            }
            iterator.remove();
        }
        this.save(getBackwardSessionKey(customerId),sessionIdSet);
        // 3. 更新反向会话
        if (StringUtils.isEmpty(excludedSessionId)) {
            logger.info("backward session is empty, remove it");
            sessionIdSet=this.fetch(getBackwardSessionKey(customerId), HashSet.class);
            sessionIdSet.remove(excludedSessionId);
            this.save(getBackwardSessionKey(customerId),sessionIdSet);
        } else {
            logger.info(("update backward session").toString());
            this.remove(getBackwardSessionKey(customerId));
        }
        logger.info(("invalidSession").toString());
    }


    /**
     * @description 删除记录的值
     * @param customerId
     */
    public void delCustomerId(String customerId){
        if(StringUtils.isNotBlank(customerId)){
            this.remove(getBackwardSessionKey(customerId));
        }
    }



    /********************************
     * @description  下面为服务的辅助类
     **********************************/
    // 反向会话放在 nkv 的 key 的前缀. 和其他业务的 key 分开
    private String backwardSessionKeyPrefix = "session.customerid.";

    // 正向会话放在 nkv 的 key 的前缀. 和其他业务的 key 分开
    // 必须和 framework-web 中的 NkvSessionDao.sessionKeyPrefix 一致
    private String forwardSessionKeyPrefix = "sessionid.";
    private String md5(String sessionId) {
        return sessionId == null ? null : DigestUtils.md5Hex(sessionId);
    }
    private String getBackwardSessionKey(String customerId) {
        return backwardSessionKeyPrefix + customerId;
    }

    private String getForwardSessionKey(String sessionId) {
        return forwardSessionKeyPrefix + sessionId;
    }

}
